<template>
  <div class="action-editor-container">
    <n-card class="action-editor-card">
      <template #header>
        <div class="card-header">
          <h1>{{ isNewAction ? '创建动作' : '编辑动作' }}</h1>
          <div class="header-actions">
            <n-button @click="goBack">
              <template #icon><n-icon><ArrowBackOutline /></n-icon></template>
              返回
            </n-button>
            <n-button type="primary" @click="saveAction">
              <template #icon><n-icon><SaveOutline /></n-icon></template>
              保存
            </n-button>
          </div>
        </div>
      </template>
      
      <div class="content-layout">
        <div class="form-section">
          <n-form
            ref="formRef"
            :model="actionForm"
            :rules="formRules"
            label-placement="left"
            label-width="100"
            require-mark-placement="right-hanging"
          >
            <n-form-item label="动作名称" path="name">
              <n-input v-model:value="actionForm.name" placeholder="请输入动作名称" />
            </n-form-item>
            
            <n-form-item label="分类" path="category">
              <n-select
                v-model:value="actionForm.category"
                :options="categoryOptions"
                placeholder="请选择分类"
                tag
                clearable
              />
            </n-form-item>
            
            <n-form-item label="持续时间" path="duration">
              <n-input-number
                v-model:value="actionForm.duration"
                :min="100"
                :max="10000"
                :step="100"
                suffix="毫秒"
              />
            </n-form-item>
            
            <n-form-item label="循环播放" path="loop">
              <n-switch v-model:value="actionForm.loop" />
            </n-form-item>
            
            <n-form-item label="缩略图" path="thumbnail">
              <n-upload
                action="#"
                :default-upload="false"
                :on-before-upload="beforeUploadThumbnail"
                accept="image/*"
                list-type="image-card"
                :max="1"
              >
                <div v-if="!actionForm.thumbnail">
                  <n-icon size="20">
                    <ImageOutline />
                  </n-icon>
                  <div>点击上传</div>
                </div>
                <img
                  v-else
                  :src="actionForm.thumbnail"
                  alt="缩略图"
                  style="max-width: 100%; max-height: 100%"
                />
              </n-upload>
            </n-form-item>
          </n-form>
        </div>
        
        <div class="preview-section">
          <div class="preview-header">
            <h3>动作预览</h3>
            <div class="preview-controls">
              <n-button size="small" @click="playAction" :disabled="isPlaying">
                <template #icon><n-icon><PlayOutline /></n-icon></template>
                播放
              </n-button>
              <n-button size="small" @click="stopAction" :disabled="!isPlaying">
                <template #icon><n-icon><StopOutline /></n-icon></template>
                停止
              </n-button>
            </div>
          </div>
          
          <div class="preview-container">
            <n-empty v-if="!character" description="请先选择角色" />
            <div v-else-if="!actionForm.keyframes || actionForm.keyframes.length === 0" class="preview-placeholder">
              <n-empty description="暂无动作数据，请添加关键帧" />
            </div>
            <div v-else class="character-preview">
              <!-- 这里将来会显示角色动作预览 -->
              <div class="preview-canvas">
                <n-empty description="动作预览将在这里显示" />
              </div>
            </div>
          </div>
        </div>
      </div>
      
      <n-divider />
      
      <div class="timeline-section">
        <div class="section-header">
          <h3>时间轴</h3>
          <div class="timeline-controls">
            <n-button size="small" @click="addKeyframe">
              <template #icon><n-icon><AddOutline /></n-icon></template>
              添加关键帧
            </n-button>
            <n-select
              v-model:value="timelineZoom"
              size="small"
              style="width: 100px"
              :options="zoomOptions"
            />
          </div>
        </div>
        
        <div class="timeline-container" v-if="actionForm.keyframes && actionForm.keyframes.length > 0">
          <div class="timeline-ruler">
            <div class="ruler-markers">
              <div 
                v-for="marker in timeMarkers" 
                :key="marker.time" 
                class="time-marker"
                :style="{ left: `${marker.position}px` }"
              >
                <div class="marker-line"></div>
                <div class="marker-label">{{ marker.label }}</div>
              </div>
            </div>
          </div>
          
          <div class="timeline-tracks">
            <div class="track-header">
              <div class="track-name">主轨道</div>
            </div>
            <div class="track-content">
              <div 
                v-for="(keyframe, index) in actionForm.keyframes" 
                :key="keyframe.id"
                class="keyframe-marker"
                :class="{ 'active-keyframe': selectedKeyframeIndex === index }"
                :style="{ left: `${getKeyframePosition(keyframe.time)}px` }"
                @click="selectKeyframe(index)"
              ></div>
            </div>
          </div>
          
          <div class="playhead" :style="{ left: `${playheadPosition}px` }"></div>
        </div>
        
        <n-empty
          v-else
          description="暂无关键帧"
        >
          <template #extra>
            <n-button @click="addKeyframe">添加关键帧</n-button>
          </template>
        </n-empty>
      </div>
      
      <n-divider />
      
      <div class="keyframe-editor" v-if="selectedKeyframeIndex !== null && actionForm.keyframes && actionForm.keyframes.length > 0">
        <h3>编辑关键帧: {{ selectedKeyframeIndex + 1 }}</h3>
        
        <n-form label-placement="left" label-width="100">
          <n-form-item label="时间">
            <n-input-number
              v-model:value="actionForm.keyframes[selectedKeyframeIndex].time"
              :min="0"
              :max="actionForm.duration"
              :step="100"
              suffix="毫秒"
            />
          </n-form-item>
          
          <n-form-item label="缓动类型">
            <n-select
              v-model:value="actionForm.keyframes[selectedKeyframeIndex].easing"
              :options="easingOptions"
              placeholder="请选择缓动类型"
            />
          </n-form-item>
          
          <n-divider />
          
          <h4>部件变换</h4>
          
          <div v-for="transform in actionForm.keyframes[selectedKeyframeIndex].transforms" :key="transform.partId" class="part-transform">
            <n-divider dashed>{{ getPartName(transform.partId) }}</n-divider>
            
            <n-form-item label="位置">
              <n-input-group>
                <n-input-number
                  v-model:value="transform.position.x"
                  placeholder="X"
                  :step="1"
                />
                <n-input-number
                  v-model:value="transform.position.y"
                  placeholder="Y"
                  :step="1"
                />
              </n-input-group>
            </n-form-item>
            
            <n-form-item label="旋转">
              <n-input-number
                v-model:value="transform.rotation"
                placeholder="度数"
                :step="1"
              />
            </n-form-item>
            
            <n-form-item label="缩放">
              <n-input-group>
                <n-input-number
                  v-model:value="transform.scale.x"
                  placeholder="X"
                  :step="0.1"
                />
                <n-input-number
                  v-model:value="transform.scale.y"
                  placeholder="Y"
                  :step="0.1"
                />
              </n-input-group>
            </n-form-item>
            
            <n-form-item label="透明度">
              <n-slider
                v-model:value="transform.opacity"
                :min="0"
                :max="1"
                :step="0.01"
                :tooltip="true"
                :format-tooltip="value => `${Math.round(value * 100)}%`"
              />
            </n-form-item>
          </div>
          
          <n-space justify="end">
            <n-button @click="deleteKeyframe(selectedKeyframeIndex)" type="error">
              <template #icon><n-icon><TrashOutline /></n-icon></template>
              删除关键帧
            </n-button>
          </n-space>
        </n-form>
      </div>
      
      <n-empty
        v-else-if="actionForm.keyframes && actionForm.keyframes.length > 0"
        description="请选择一个关键帧进行编辑"
      />
    </n-card>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, computed, onMounted, onBeforeUnmount, h } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { useMessage } from 'naive-ui'
import { v4 as uuidv4 } from 'uuid'
import {
  NCard,
  NButton,
  NIcon,
  NForm,
  NFormItem,
  NInput,
  NInputNumber,
  NInputGroup,
  NSelect,
  NSwitch,
  NSlider,
  NUpload,
  NEmpty,
  NDivider,
  NSpace,
  FormInst
} from 'naive-ui'
import {
  ArrowBackOutline,
  SaveOutline,
  ImageOutline,
  AddOutline,
  TrashOutline,
  PlayOutline,
  StopOutline
} from '@vicons/ionicons5'
import { useProjectStore } from '../../stores/projectStore'
import type { Character, CharacterPart, Vector2 } from '../../types/project'

// 定义动作和关键帧类型
interface PartTransform {
  partId: string;
  position: Vector2;
  rotation: number;
  scale: Vector2;
  opacity: number;
}

interface Keyframe {
  id: string;
  time: number;
  easing: string;
  transforms: PartTransform[];
}

interface Action {
  id: string;
  name: string;
  characterId: string;
  duration: number;
  loop: boolean;
  keyframes: Keyframe[];
  thumbnail?: string;
  category?: string;
  tags?: string[];
}

const route = useRoute()
const router = useRouter()
const message = useMessage()
const projectStore = useProjectStore()

// 表单引用
const formRef = ref<FormInst | null>(null)

// 获取动作ID和角色ID
const actionId = computed(() => route.params.id as string | undefined)
const characterId = computed(() => route.query.characterId as string)
const projectId = computed(() => route.query.projectId as string)
const isNewAction = computed(() => !actionId.value)

// 角色数据
const character = ref<Character | null>(null)

// 动作表单数据
const actionForm = reactive<Partial<Action>>({
  id: '',
  name: '',
  characterId: '',
  duration: 2000,
  loop: false,
  keyframes: [],
  thumbnail: '',
  category: ''
})

// 分类选项
const categoryOptions = [
  { label: '走路', value: '走路' },
  { label: '跑步', value: '跑步' },
  { label: '跳跃', value: '跳跃' },
  { label: '攻击', value: '攻击' },
  { label: '受伤', value: '受伤' },
  { label: '站立', value: '站立' },
  { label: '其他', value: '其他' }
]

// 缓动选项
const easingOptions = [
  { label: '线性', value: 'linear' },
  { label: '缓入', value: 'easeIn' },
  { label: '缓出', value: 'easeOut' },
  { label: '缓入缓出', value: 'easeInOut' },
  { label: '弹性', value: 'elastic' },
  { label: '弹跳', value: 'bounce' }
]

// 表单验证规则
const formRules = {
  name: {
    required: true,
    message: '请输入动作名称',
    trigger: 'blur'
  },
  duration: {
    required: true,
    trigger: 'blur',
    validator: (_rule: any, value: number) => {
      return value >= 100 && value <= 10000
    },
    message: '请输入有效的持续时间'
  }
}

// 时间轴相关
const timelineZoom = ref(1)
const zoomOptions = [
  { label: '25%', value: 0.25 },
  { label: '50%', value: 0.5 },
  { label: '100%', value: 1 },
  { label: '200%', value: 2 },
  { label: '400%', value: 4 }
]

// 选中的关键帧
const selectedKeyframeIndex = ref<number | null>(null)

// 播放状态
const isPlaying = ref(false)
const playheadPosition = ref(0)
let animationFrameId: number | null = null
let startTime: number | null = null
let currentPlayTime = ref(0)

// 时间标记
const timeMarkers = computed(() => {
  if (!actionForm.duration) return []
  
  const markers: Array<{time: number, position: number, label: string}> = []
  const step = 500 // 每500毫秒一个标记
  const maxTime = actionForm.duration
  
  for (let time = 0; time <= maxTime; time += step) {
    markers.push({
      time,
      position: getKeyframePosition(time),
      label: (time / 1000).toFixed(1) + 's'
    })
  }
  
  return markers
})

// 获取关键帧在时间轴上的位置
const getKeyframePosition = (time: number) => {
  const pixelsPerMs = 0.1 * timelineZoom.value
  return time * pixelsPerMs
}

// 获取部件名称
const getPartName = (partId: string) => {
  if (!character.value) return '未知部件'
  
  const part = character.value.parts.find(p => p.id === partId)
  return part ? part.name : '未知部件'
}

// 加载角色数据
const loadCharacter = async () => {
  if (!characterId.value) {
    message.error('缺少角色ID')
    return
  }
  
  try {
    const result = await projectStore.fetchCharacter(characterId.value)
    if (result) {
      character.value = result
    } else {
      message.error('加载角色数据失败')
    }
  } catch (error) {
    console.error('加载角色数据错误:', error)
    message.error('加载角色数据时发生错误')
  }
}

// 加载动作数据
const loadAction = async () => {
  if (!actionId.value || !characterId.value) return
  
  try {
    // 这里假设 projectStore 有 fetchAction 方法
    // 实际项目中需要实现此方法或通过其他方式获取动作数据
    const result = await projectStore.fetchAction(actionId.value)
    if (result) {
      Object.assign(actionForm, result)
    } else {
      message.error('加载动作数据失败')
    }
  } catch (error) {
    console.error('加载动作数据错误:', error)
    message.error('加载动作数据时发生错误')
  }
}

// 初始化动作数据
const initAction = () => {
  actionForm.id = uuidv4()
  actionForm.characterId = characterId.value
  actionForm.name = '新建动作'
  actionForm.duration = 2000
  actionForm.loop = false
  actionForm.keyframes = []
}

// 保存动作
const saveAction = async () => {
  try {
    await formRef.value?.validate()
    
    // 这里假设 projectStore 有 saveAction 方法
    // 实际项目中需要实现此方法或通过其他方式保存动作数据
    const result = await projectStore.saveAction(actionForm as Action)
    if (result) {
      message.success('保存成功')
      if (isNewAction.value) {
        // 如果是新建，保存后跳转到编辑页面
        router.replace(`/character/action/${result.id}?characterId=${characterId.value}&projectId=${projectId.value}`)
      }
    } else {
      message.error('保存失败')
    }
  } catch (error) {
    console.error('保存动作错误:', error)
    message.error('表单验证失败或保存时发生错误')
  }
}

// 返回上一页
const goBack = () => {
  router.back()
}

// 添加关键帧
const addKeyframe = () => {
  if (!character.value || !character.value.parts.length) {
    message.warning('请先添加角色部件')
    return
  }
  
  // 创建部件变换数据
  const transforms: PartTransform[] = character.value.parts.map(part => ({
    partId: part.id,
    position: { ...part.position },
    rotation: part.rotation,
    scale: { ...part.scale },
    opacity: part.opacity
  }))
  
  // 创建新关键帧
  const newKeyframe: Keyframe = {
    id: uuidv4(),
    time: actionForm.keyframes?.length ? Math.min(actionForm.duration || 2000, (actionForm.keyframes[actionForm.keyframes.length - 1].time + 500)) : 0,
    easing: 'linear',
    transforms
  }
  
  actionForm.keyframes = actionForm.keyframes || []
  actionForm.keyframes.push(newKeyframe)
  
  // 选中新添加的关键帧
  selectedKeyframeIndex.value = actionForm.keyframes.length - 1
}

// 选择关键帧
const selectKeyframe = (index: number) => {
  selectedKeyframeIndex.value = index
}

// 删除关键帧
const deleteKeyframe = (index: number) => {
  if (!actionForm.keyframes) return
  
  actionForm.keyframes.splice(index, 1)
  if (actionForm.keyframes.length === 0) {
    selectedKeyframeIndex.value = null
  } else if (selectedKeyframeIndex.value === index) {
    selectedKeyframeIndex.value = Math.min(index, actionForm.keyframes.length - 1)
  } else if (selectedKeyframeIndex.value && selectedKeyframeIndex.value > index) {
    selectedKeyframeIndex.value--
  }
}

// 播放动作
const playAction = () => {
  if (!actionForm.keyframes || actionForm.keyframes.length < 2) {
    message.warning('至少需要两个关键帧才能播放动作')
    return
  }
  
  isPlaying.value = true
  startTime = performance.now()
  currentPlayTime.value = 0
  
  const animate = (timestamp: number) => {
    if (!startTime) startTime = timestamp
    const elapsed = timestamp - startTime
    
    currentPlayTime.value = elapsed % (actionForm.duration || 2000)
    playheadPosition.value = getKeyframePosition(currentPlayTime.value)
    
    if (isPlaying.value) {
      if (!actionForm.loop && elapsed >= (actionForm.duration || 2000)) {
        stopAction()
      } else {
        animationFrameId = requestAnimationFrame(animate)
      }
    }
  }
  
  animationFrameId = requestAnimationFrame(animate)
}

// 停止播放
const stopAction = () => {
  isPlaying.value = false
  if (animationFrameId !== null) {
    cancelAnimationFrame(animationFrameId)
    animationFrameId = null
  }
  currentPlayTime.value = 0
  playheadPosition.value = 0
}

// 上传缩略图前处理
const beforeUploadThumbnail = (data: any) => {
  const reader = new FileReader()
  reader.onload = (e) => {
    actionForm.thumbnail = e.target?.result as string
  }
  reader.readAsDataURL(data.file.file)
  return false // 阻止默认上传行为
}

// 初始化
onMounted(async () => {
  await loadCharacter()
  
  if (actionId.value) {
    await loadAction()
  } else {
    initAction()
  }
})

// 清理
onBeforeUnmount(() => {
  if (animationFrameId !== null) {
    cancelAnimationFrame(animationFrameId)
  }
})
</script>

<style lang="scss" scoped>
.action-editor-container {
  padding: 20px;
  height: 100%;
  overflow-y: auto;
  
  .action-editor-card {
    .card-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      
      h1 {
        margin: 0;
        font-size: 24px;
        font-weight: 500;
      }
      
      .header-actions {
        display: flex;
        gap: 12px;
      }
    }
  }
  
  .content-layout {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 24px;
    margin-bottom: 20px;
    
    .form-section {
      padding-right: 12px;
    }
    
    .preview-section {
      .preview-header {
        display: flex;
        justify-content: space-between;
        align-items: center;
        margin-bottom: 16px;
        
        h3 {
          margin: 0;
        }
        
        .preview-controls {
          display: flex;
          gap: 8px;
        }
      }
      
      .preview-container {
        border: 1px dashed var(--border-color);
        border-radius: 4px;
        height: 300px;
        display: flex;
        align-items: center;
        justify-content: center;
        
        .character-preview {
          width: 100%;
          height: 100%;
          display: flex;
          align-items: center;
          justify-content: center;
          
          .preview-canvas {
            width: 100%;
            height: 100%;
            display: flex;
            align-items: center;
            justify-content: center;
          }
        }
      }
    }
  }
  
  .timeline-section {
    .section-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 16px;
      
      h3 {
        margin: 0;
      }
      
      .timeline-controls {
        display: flex;
        gap: 12px;
        align-items: center;
      }
    }
    
    .timeline-container {
      position: relative;
      border: 1px solid var(--border-color);
      border-radius: 4px;
      margin-bottom: 20px;
      height: 120px;
      overflow-x: auto;
      
      .timeline-ruler {
        height: 30px;
        border-bottom: 1px solid var(--border-color);
        position: relative;
        
        .ruler-markers {
          position: relative;
          height: 100%;
          
          .time-marker {
            position: absolute;
            height: 100%;
            
            .marker-line {
              position: absolute;
              top: 15px;
              height: 15px;
              width: 1px;
              background-color: var(--border-color);
            }
            
            .marker-label {
              position: absolute;
              top: 0;
              transform: translateX(-50%);
              font-size: 12px;
              color: var(--text-color-secondary);
            }
          }
        }
      }
      
      .timeline-tracks {
        display: flex;
        height: 90px;
        
        .track-header {
          width: 100px;
          border-right: 1px solid var(--border-color);
          padding: 8px;
          
          .track-name {
            font-size: 12px;
            font-weight: 500;
          }
        }
        
        .track-content {
          flex-grow: 1;
          position: relative;
          height: 100%;
          
          .keyframe-marker {
            position: absolute;
            top: 50%;
            transform: translateY(-50%);
            width: 12px;
            height: 12px;
            background-color: var(--primary-color);
            border-radius: 50%;
            margin-left: -6px;
            cursor: pointer;
            
            &.active-keyframe {
              border: 2px solid white;
              box-shadow: 0 0 0 1px var(--primary-color);
            }
          }
        }
      }
      
      .playhead {
        position: absolute;
        top: 0;
        height: 100%;
        width: 2px;
        background-color: red;
        pointer-events: none;
      }
    }
  }
  
  .keyframe-editor {
    h3 {
      margin-top: 0;
      margin-bottom: 16px;
    }
    
    h4 {
      margin-top: 16px;
      margin-bottom: 8px;
    }
    
    .part-transform {
      margin-bottom: 16px;
    }
  }
}

/* 响应式调整 */
@media (max-width: 768px) {
  .action-editor-container {
    padding: 10px;
    
    .content-layout {
      grid-template-columns: 1fr;
      
      .preview-section {
        margin-top: 20px;
      }
    }
  }
}
</style> 